﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XFGameFramework.OctreeSystem;

public abstract class OctreeBounds : MonoBehaviour
{

    #region 字段

    private OctreeObject octreeObject;

    #endregion

    #region 属性

    public OctreeObject OctreeObject => octreeObject;

    #endregion

    /// <summary>
    /// 是否和某一个Bounds相交
    /// </summary>
    /// <param name="bounds"></param>
    /// <returns></returns>
    public abstract bool Intersects(Bounds bounds);

    /// <summary>
    /// 是否和某一个OctreeBounds相交
    /// </summary>
    /// <param name="bounds"></param>
    /// <returns></returns>
    public abstract bool Intersects(OctreeBounds octreeBounds);

    /// <summary>
    /// 是否和某一个射线相交 、
    ///  box: 计算该射线与box的6个面相交的点 是否满足
    ///  sphere: 计算该射线到圆心的距离是否满
    ///  圆柱: 计算该射线到中心点的距离 在 平面 和 竖直方向的投影距离 
    ///  
    /// 后面如果拓展CircleRaycast 可以在此基础上调整 
    /// </summary>
    /// <param name="ray"></param>
    /// <returns></returns>
    public abstract bool IntersectRay(Ray ray, float distance = -1);

    /// <summary>
    /// 
    /// </summary>
    /// <param name="ray"></param>
    /// <param name="point"></param>
    /// <returns></returns>
    public abstract bool IntersectRay(Ray ray, out IntersectInfo info,float distance = -1);


    /// <summary>
    /// 判断该区域是否包含某一个点
    /// </summary>
    /// <param name="point"></param>
    /// <returns></returns>
    public abstract bool Contains(Vector3 point);

    /// <summary>
    /// 获取该区域距离该点最近的点
    /// </summary>
    /// <param name="point"></param>
    /// <returns></returns>
    public abstract Vector3 ClosestPoint(Vector3 point);


    public abstract Bounds GetBounds();

    #region 生命周期

    protected virtual void Awake()
    {
        octreeObject = transform.GetComponentInParent<OctreeObject>();
    }

    protected virtual void OnTransformParentChanged()
    {
        if (!gameObject.activeInHierarchy)
            return;

        if (octreeObject)
            octreeObject.RemoveBounds(this);

        octreeObject = transform.GetComponentInParent<OctreeObject>();

        if (octreeObject)
            octreeObject.AddBounds(this);
    }

    private void OnEnable()
    {
        if (octreeObject)
            octreeObject.AddBounds(this);
    }

    private void OnDisable()
    {
        if (octreeObject)
            octreeObject.RemoveBounds(this);
    }

    #endregion
}
